/*
 * oled.c
 *
 *  Created on: 2022年3月12日
 *      Author: Naming8104
 */
#include "oled.h"

#include "spi.h"
#include "string.h"

const uint8_t F6x8[] =
{
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sp
  0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, // !
  0x00, 0x00, 0x07, 0x00, 0x07, 0x00, // "
  0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14, // #
  0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12, // $
  0x00, 0x62, 0x64, 0x08, 0x13, 0x23, // %
  0x00, 0x36, 0x49, 0x55, 0x22, 0x50, // &
  0x00, 0x00, 0x05, 0x03, 0x00, 0x00, // '
  0x00, 0x00, 0x1c, 0x22, 0x41, 0x00, // (
  0x00, 0x00, 0x41, 0x22, 0x1c, 0x00, // )
  0x00, 0x14, 0x08, 0x3E, 0x08, 0x14, // *
  0x00, 0x08, 0x08, 0x3E, 0x08, 0x08, // +
  0x00, 0x00, 0x00, 0xA0, 0x60, 0x00, // ,
  0x00, 0x08, 0x08, 0x08, 0x08, 0x08, // -
  0x00, 0x00, 0x60, 0x60, 0x00, 0x00, // .
  0x00, 0x20, 0x10, 0x08, 0x04, 0x02, // /
  0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E, // 0
  0x00, 0x00, 0x42, 0x7F, 0x40, 0x00, // 1
  0x00, 0x42, 0x61, 0x51, 0x49, 0x46, // 2
  0x00, 0x21, 0x41, 0x45, 0x4B, 0x31, // 3
  0x00, 0x18, 0x14, 0x12, 0x7F, 0x10, // 4
  0x00, 0x27, 0x45, 0x45, 0x45, 0x39, // 5
  0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30, // 6
  0x00, 0x01, 0x71, 0x09, 0x05, 0x03, // 7
  0x00, 0x36, 0x49, 0x49, 0x49, 0x36, // 8
  0x00, 0x06, 0x49, 0x49, 0x29, 0x1E, // 9
  0x00, 0x00, 0x36, 0x36, 0x00, 0x00, // :
  0x00, 0x00, 0x56, 0x36, 0x00, 0x00, // ;
  0x00, 0x08, 0x14, 0x22, 0x41, 0x00, // <
  0x00, 0x14, 0x14, 0x14, 0x14, 0x14, // =
  0x00, 0x00, 0x41, 0x22, 0x14, 0x08, // >
  0x00, 0x02, 0x01, 0x51, 0x09, 0x06, // ?
  0x00, 0x32, 0x49, 0x59, 0x51, 0x3E, // @
  0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C, // A
  0x00, 0x7F, 0x49, 0x49, 0x49, 0x36, // B
  0x00, 0x3E, 0x41, 0x41, 0x41, 0x22, // C
  0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C, // D
  0x00, 0x7F, 0x49, 0x49, 0x49, 0x41, // E
  0x00, 0x7F, 0x09, 0x09, 0x09, 0x01, // F
  0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A, // G
  0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F, // H
  0x00, 0x00, 0x41, 0x7F, 0x41, 0x00, // I
  0x00, 0x20, 0x40, 0x41, 0x3F, 0x01, // J
  0x00, 0x7F, 0x08, 0x14, 0x22, 0x41, // K
  0x00, 0x7F, 0x40, 0x40, 0x40, 0x40, // L
  0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F, // M
  0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F, // N
  0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E, // O
  0x00, 0x7F, 0x09, 0x09, 0x09, 0x06, // P
  0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E, // Q
  0x00, 0x7F, 0x09, 0x19, 0x29, 0x46, // R
  0x00, 0x46, 0x49, 0x49, 0x49, 0x31, // S
  0x00, 0x01, 0x01, 0x7F, 0x01, 0x01, // T
  0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F, // U
  0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F, // V
  0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F, // W
  0x00, 0x63, 0x14, 0x08, 0x14, 0x63, // X
  0x00, 0x07, 0x08, 0x70, 0x08, 0x07, // Y
  0x00, 0x61, 0x51, 0x49, 0x45, 0x43, // Z
  0x00, 0x00, 0x7F, 0x41, 0x41, 0x00, // [
  0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55, // 55
  0x00, 0x00, 0x41, 0x41, 0x7F, 0x00, // ]
  0x00, 0x04, 0x02, 0x01, 0x02, 0x04, // ^
  0x00, 0x40, 0x40, 0x40, 0x40, 0x40, // _
  0x00, 0x00, 0x01, 0x02, 0x04, 0x00, // '
  0x00, 0x20, 0x54, 0x54, 0x54, 0x78, // a
  0x00, 0x7F, 0x48, 0x44, 0x44, 0x38, // b
  0x00, 0x38, 0x44, 0x44, 0x44, 0x20, // c
  0x00, 0x38, 0x44, 0x44, 0x48, 0x7F, // d
  0x00, 0x38, 0x54, 0x54, 0x54, 0x18, // e
  0x00, 0x08, 0x7E, 0x09, 0x01, 0x02, // f
  0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C, // g
  0x00, 0x7F, 0x08, 0x04, 0x04, 0x78, // h
  0x00, 0x00, 0x44, 0x7D, 0x40, 0x00, // i
  0x00, 0x40, 0x80, 0x84, 0x7D, 0x00, // j
  0x00, 0x7F, 0x10, 0x28, 0x44, 0x00, // k
  0x00, 0x00, 0x41, 0x7F, 0x40, 0x00, // l
  0x00, 0x7C, 0x04, 0x18, 0x04, 0x78, // m
  0x00, 0x7C, 0x08, 0x04, 0x04, 0x78, // n
  0x00, 0x38, 0x44, 0x44, 0x44, 0x38, // o
  0x00, 0xFC, 0x24, 0x24, 0x24, 0x18, // p
  0x00, 0x18, 0x24, 0x24, 0x18, 0xFC, // q
  0x00, 0x7C, 0x08, 0x04, 0x04, 0x08, // r
  0x00, 0x48, 0x54, 0x54, 0x54, 0x20, // s
  0x00, 0x04, 0x3F, 0x44, 0x40, 0x20, // t
  0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C, // u
  0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C, // v
  0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C, // w
  0x00, 0x44, 0x28, 0x10, 0x28, 0x44, // x
  0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C, // y
  0x00, 0x44, 0x64, 0x54, 0x4C, 0x44, // z
  0x14, 0x14, 0x14, 0x14, 0x14, 0x14  // horiz lines
};

//======================================================
// 128X64I液晶底层驱动[8X16]字体库
// 设计者: powerint
// 描  述: [8X16]西文字符的字模数据 (纵向取模,字节倒序)
// !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
//======================================================
const uint8_t F8X16[1520] =
{
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0
  0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x30, 0x00, 0x00, 0x00, //! 1
  0x00, 0x10, 0x0C, 0x06, 0x10, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //"2
  0x40, 0xC0, 0x78, 0x40, 0xC0, 0x78, 0x40, 0x00, 0x04, 0x3F, 0x04, 0x04, 0x3F, 0x04, 0x04, 0x00, //#3
  0x00, 0x70, 0x88, 0xFC, 0x08, 0x30, 0x00, 0x00, 0x00, 0x18, 0x20, 0xFF, 0x21, 0x1E, 0x00, 0x00, //$4
  0xF0, 0x08, 0xF0, 0x00, 0xE0, 0x18, 0x00, 0x00, 0x00, 0x21, 0x1C, 0x03, 0x1E, 0x21, 0x1E, 0x00, //%5
  0x00, 0xF0, 0x08, 0x88, 0x70, 0x00, 0x00, 0x00, 0x1E, 0x21, 0x23, 0x24, 0x19, 0x27, 0x21, 0x10, //&6
  0x10, 0x16, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //'7
  0x00, 0x00, 0x00, 0xE0, 0x18, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x07, 0x18, 0x20, 0x40, 0x00, //(8
  0x00, 0x02, 0x04, 0x18, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x18, 0x07, 0x00, 0x00, 0x00, //)9
  0x40, 0x40, 0x80, 0xF0, 0x80, 0x40, 0x40, 0x00, 0x02, 0x02, 0x01, 0x0F, 0x01, 0x02, 0x02, 0x00, //*10
  0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x1F, 0x01, 0x01, 0x01, 0x00, //+11
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xB0, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, //,12
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, //-13
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, //.14
  0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x18, 0x04, 0x00, 0x60, 0x18, 0x06, 0x01, 0x00, 0x00, 0x00, /// 15
  0x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x10, 0x0F, 0x00, // 016
  0x00, 0x10, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // 117
  0x00, 0x70, 0x08, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, 0x30, 0x28, 0x24, 0x22, 0x21, 0x30, 0x00, // 218
  0x00, 0x30, 0x08, 0x88, 0x88, 0x48, 0x30, 0x00, 0x00, 0x18, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00, // 319
  0x00, 0x00, 0xC0, 0x20, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x07, 0x04, 0x24, 0x24, 0x3F, 0x24, 0x00, // 420
  0x00, 0xF8, 0x08, 0x88, 0x88, 0x08, 0x08, 0x00, 0x00, 0x19, 0x21, 0x20, 0x20, 0x11, 0x0E, 0x00, // 521
  0x00, 0xE0, 0x10, 0x88, 0x88, 0x18, 0x00, 0x00, 0x00, 0x0F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00, // 622
  0x00, 0x38, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, // 723
  0x00, 0x70, 0x88, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, 0x1C, 0x22, 0x21, 0x21, 0x22, 0x1C, 0x00, // 824
  0x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x00, 0x31, 0x22, 0x22, 0x11, 0x0F, 0x00, // 925
  0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, //: 26
  0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x00, 0x00, 0x00, 0x00, //;27
  0x00, 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, //<28
  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, //=29
  0x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, //>30
  0x00, 0x70, 0x48, 0x08, 0x08, 0x08, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x30, 0x36, 0x01, 0x00, 0x00, //?31
  0xC0, 0x30, 0xC8, 0x28, 0xE8, 0x10, 0xE0, 0x00, 0x07, 0x18, 0x27, 0x24, 0x23, 0x14, 0x0B, 0x00, //@32
  0x00, 0x00, 0xC0, 0x38, 0xE0, 0x00, 0x00, 0x00, 0x20, 0x3C, 0x23, 0x02, 0x02, 0x27, 0x38, 0x20, // A33
  0x08, 0xF8, 0x88, 0x88, 0x88, 0x70, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00, // B34
  0xC0, 0x30, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 0x07, 0x18, 0x20, 0x20, 0x20, 0x10, 0x08, 0x00, // C35
  0x08, 0xF8, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00, // D36
  0x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x23, 0x20, 0x18, 0x00, // E37
  0x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00, // F38
  0xC0, 0x30, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x07, 0x18, 0x20, 0x20, 0x22, 0x1E, 0x02, 0x00, // G39
  0x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08, 0x20, 0x3F, 0x21, 0x01, 0x01, 0x21, 0x3F, 0x20, // H40
  0x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // I41
  0x00, 0x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00, 0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00, 0x00, // J42
  0x08, 0xF8, 0x88, 0xC0, 0x28, 0x18, 0x08, 0x00, 0x20, 0x3F, 0x20, 0x01, 0x26, 0x38, 0x20, 0x00, // K43
  0x08, 0xF8, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x20, 0x30, 0x00, // L44
  0x08, 0xF8, 0xF8, 0x00, 0xF8, 0xF8, 0x08, 0x00, 0x20, 0x3F, 0x00, 0x3F, 0x00, 0x3F, 0x20, 0x00, // M45
  0x08, 0xF8, 0x30, 0xC0, 0x00, 0x08, 0xF8, 0x08, 0x20, 0x3F, 0x20, 0x00, 0x07, 0x18, 0x3F, 0x00, // N46
  0xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00, // O47
  0x08, 0xF8, 0x08, 0x08, 0x08, 0x08, 0xF0, 0x00, 0x20, 0x3F, 0x21, 0x01, 0x01, 0x01, 0x00, 0x00, // P48
  0xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x0F, 0x18, 0x24, 0x24, 0x38, 0x50, 0x4F, 0x00, // Q49
  0x08, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x70, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x03, 0x0C, 0x30, 0x20, // R50
  0x00, 0x70, 0x88, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x38, 0x20, 0x21, 0x21, 0x22, 0x1C, 0x00, // S51
  0x18, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x18, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00, // T52
  0x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, // U53
  0x08, 0x78, 0x88, 0x00, 0x00, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x07, 0x38, 0x0E, 0x01, 0x00, 0x00, // V54
  0xF8, 0x08, 0x00, 0xF8, 0x00, 0x08, 0xF8, 0x00, 0x03, 0x3C, 0x07, 0x00, 0x07, 0x3C, 0x03, 0x00, // W55
  0x08, 0x18, 0x68, 0x80, 0x80, 0x68, 0x18, 0x08, 0x20, 0x30, 0x2C, 0x03, 0x03, 0x2C, 0x30, 0x20, // X56
  0x08, 0x38, 0xC8, 0x00, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00, // Y57
  0x10, 0x08, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00, 0x20, 0x38, 0x26, 0x21, 0x20, 0x20, 0x18, 0x00, // Z58
  0x00, 0x00, 0x00, 0xFE, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x40, 0x40, 0x40, 0x00, //[59
  0x00, 0x0C, 0x30, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x38, 0xC0, 0x00, //\60
  0x00, 0x02, 0x02, 0x02, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x7F, 0x00, 0x00, 0x00, //]61
  0x00, 0x00, 0x04, 0x02, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //^62
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, //_63
  0x00, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //`64
  0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x19, 0x24, 0x22, 0x22, 0x22, 0x3F, 0x20, // a65
  0x08, 0xF8, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00, // b66
  0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0x20, 0x11, 0x00, // c67
  0x00, 0x00, 0x00, 0x80, 0x80, 0x88, 0xF8, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0x10, 0x3F, 0x20, // d68
  0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x22, 0x22, 0x22, 0x13, 0x00, // e69
  0x00, 0x80, 0x80, 0xF0, 0x88, 0x88, 0x88, 0x18, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // f70
  0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x6B, 0x94, 0x94, 0x94, 0x93, 0x60, 0x00, // g71
  0x08, 0xF8, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20, // h72
  0x00, 0x80, 0x98, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // i73
  0x00, 0x00, 0x00, 0x80, 0x98, 0x98, 0x00, 0x00, 0x00, 0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00, // j74
  0x08, 0xF8, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x20, 0x3F, 0x24, 0x02, 0x2D, 0x30, 0x20, 0x00, // k75
  0x00, 0x08, 0x08, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // l76
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x3F, 0x20, 0x00, 0x3F, // m77
  0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20, // n78
  0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, // o79
  0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xA1, 0x20, 0x20, 0x11, 0x0E, 0x00, // p80
  0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0xA0, 0xFF, 0x80, // q81
  0x80, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x20, 0x20, 0x3F, 0x21, 0x20, 0x00, 0x01, 0x00, // r82
  0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x33, 0x24, 0x24, 0x24, 0x24, 0x19, 0x00, // s83
  0x00, 0x80, 0x80, 0xE0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x00, 0x00, // t84
  0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x10, 0x3F, 0x20, // u85
  0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x01, 0x0E, 0x30, 0x08, 0x06, 0x01, 0x00, // v86
  0x80, 0x80, 0x00, 0x80, 0x00, 0x80, 0x80, 0x80, 0x0F, 0x30, 0x0C, 0x03, 0x0C, 0x30, 0x0F, 0x00, // w87
  0x00, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x31, 0x2E, 0x0E, 0x31, 0x20, 0x00, // x88
  0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x81, 0x8E, 0x70, 0x18, 0x06, 0x01, 0x00, // y89
  0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x21, 0x30, 0x2C, 0x22, 0x21, 0x30, 0x00, // z90
  0x00, 0x00, 0x00, 0x00, 0x80, 0x7C, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x40, 0x40, //{91
  0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, //|92
  0x00, 0x02, 0x02, 0x7C, 0x80, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x3F, 0x00, 0x00, 0x00, 0x00, //}93
  0x00, 0x06, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //~94
};

static const char *F16x16_Idx = "修下再功密成手指按改次码确纹解认请锁开门中…太短重试不一致";

static const uint8_t F16x16[] = {

  0x40, 0x20, 0xf8, 0x07, 0xf0, 0xa0, 0x90, 0x4c, 0x57, 0x24, 0xa4, 0x54, 0x4c, 0x80, 0x80, 0x00, 
  0x00, 0x00, 0xff, 0x00, 0x1f, 0x80, 0x92, 0x52, 0x49, 0x29, 0x24, 0x12, 0x08, 0x00, 0x00, 0x00, //修 0

  0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0xfe, 0x02, 0x02, 0x42, 0x82, 0x02, 0x02, 0x02, 0x02, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, //下 1

  0x02, 0x02, 0xf2, 0x92, 0x92, 0x92, 0x92, 0xfe, 0x92, 0x92, 0x92, 0x92, 0xf2, 0x02, 0x02, 0x00, 
  0x04, 0x04, 0xff, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04, 0x04, 0x44, 0x84, 0x7f, 0x04, 0x04, 0x00, //再 2

  0x08, 0x08, 0x08, 0xf8, 0x08, 0x08, 0x08, 0x10, 0x10, 0xff, 0x10, 0x10, 0x10, 0xf0, 0x00, 0x00, 
  0x10, 0x30, 0x10, 0x1f, 0x08, 0x88, 0x48, 0x30, 0x0e, 0x01, 0x40, 0x80, 0x40, 0x3f, 0x00, 0x00, //功 3

  0x10, 0x8c, 0x44, 0x04, 0xe4, 0x04, 0x95, 0xa6, 0x44, 0x24, 0x14, 0x84, 0x44, 0x94, 0x0c, 0x00, 
  0x02, 0x02, 0x7a, 0x41, 0x41, 0x43, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x43, 0xf8, 0x00, 0x00, 0x00, //密 4

  0x00, 0x00, 0xf8, 0x88, 0x88, 0x88, 0x88, 0x08, 0x08, 0xff, 0x08, 0x09, 0x0a, 0xc8, 0x08, 0x00, 
  0x80, 0x60, 0x1f, 0x00, 0x10, 0x20, 0x1f, 0x80, 0x40, 0x21, 0x16, 0x18, 0x26, 0x41, 0xf8, 0x00, //成 5

  0x00, 0x00, 0x24, 0x24, 0x24, 0x24, 0x24, 0xfc, 0x22, 0x22, 0x22, 0x23, 0x22, 0x00, 0x00, 0x00, 
  0x02, 0x02, 0x02, 0x02, 0x02, 0x42, 0x82, 0x7f, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, //手 6

  0x10, 0x10, 0x10, 0xff, 0x10, 0x90, 0x00, 0x3f, 0x48, 0x48, 0x44, 0x44, 0x44, 0x42, 0x70, 0x00, 
  0x04, 0x44, 0x82, 0x7f, 0x01, 0x00, 0x00, 0xff, 0x49, 0x49, 0x49, 0x49, 0x49, 0xff, 0x00, 0x00, //指 7

  0x10, 0x10, 0x10, 0xff, 0x90, 0x20, 0x98, 0x88, 0x88, 0xe9, 0x8e, 0x88, 0x88, 0xa8, 0x98, 0x00, 
  0x02, 0x42, 0x81, 0x7f, 0x00, 0x00, 0x80, 0x84, 0x4b, 0x28, 0x10, 0x28, 0x47, 0x80, 0x00, 0x00, //按 8

  0x04, 0x84, 0x84, 0x84, 0x84, 0xfc, 0x40, 0x30, 0xcc, 0x0b, 0x08, 0x08, 0xf8, 0x08, 0x08, 0x00, 
  0x00, 0x7f, 0x20, 0x10, 0x10, 0x08, 0x80, 0x40, 0x21, 0x16, 0x08, 0x16, 0x21, 0x40, 0x80, 0x00, //改 9

  0x00, 0x02, 0x0c, 0x80, 0x60, 0x80, 0x40, 0x30, 0x0f, 0xc8, 0x08, 0x08, 0x28, 0x18, 0x00, 0x00, 
  0x02, 0x02, 0x7e, 0x01, 0x80, 0x40, 0x20, 0x18, 0x06, 0x01, 0x06, 0x18, 0x20, 0x40, 0x80, 0x00, //次 10

  0x04, 0x84, 0xe4, 0x5c, 0x44, 0xc4, 0x00, 0x02, 0xf2, 0x82, 0x82, 0x82, 0xfe, 0x80, 0x80, 0x00, 
  0x02, 0x01, 0x7f, 0x10, 0x10, 0x3f, 0x00, 0x08, 0x08, 0x08, 0x08, 0x48, 0x88, 0x40, 0x3f, 0x00, //码 11

  0x04, 0x84, 0xe4, 0x5c, 0x44, 0xc4, 0x20, 0x10, 0xe8, 0x27, 0x24, 0xe4, 0x34, 0x2c, 0xe0, 0x00, 
  0x02, 0x01, 0x7f, 0x10, 0x10, 0x3f, 0x80, 0x60, 0x1f, 0x09, 0x09, 0x3f, 0x49, 0x89, 0x7f, 0x00, //确 12

  0x20, 0x30, 0xac, 0x63, 0x10, 0x08, 0x08, 0xf8, 0x09, 0x0e, 0x08, 0xf8, 0x08, 0x08, 0x00, 0x00, 
  0x22, 0x67, 0x22, 0x12, 0x92, 0x80, 0x40, 0x21, 0x16, 0x08, 0x16, 0x21, 0x40, 0x80, 0x80, 0x00, //纹 13

  0x20, 0x10, 0xec, 0x27, 0xf4, 0x2c, 0xe0, 0x00, 0x22, 0x92, 0x0e, 0xd2, 0x22, 0x1e, 0x00, 0x00, 
  0x80, 0x60, 0x1f, 0x09, 0x3f, 0x89, 0xff, 0x00, 0x0a, 0x09, 0x09, 0xff, 0x09, 0x09, 0x08, 0x00, //解 14

  0x40, 0x40, 0x42, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x3f, 0x90, 0x48, 0x20, 0x18, 0x07, 0x00, 0x07, 0x18, 0x20, 0x40, 0x80, 0x00, //认 15

  0x40, 0x42, 0xcc, 0x00, 0x00, 0x44, 0x54, 0x54, 0x54, 0x7f, 0x54, 0x54, 0x54, 0x44, 0x40, 0x00, 
  0x00, 0x00, 0x7f, 0x20, 0x10, 0x00, 0xff, 0x15, 0x15, 0x15, 0x55, 0x95, 0x7f, 0x00, 0x00, 0x00, //请 16

  0x20, 0x10, 0x2c, 0xe7, 0x24, 0x24, 0x00, 0xe2, 0x2c, 0x20, 0xbf, 0x20, 0x28, 0xe6, 0x00, 0x00, 
  0x01, 0x01, 0x01, 0x7f, 0x21, 0x11, 0x80, 0x4f, 0x20, 0x10, 0x0f, 0x10, 0x20, 0x4f, 0x80, 0x00, //锁 17

  0x80, 0x82, 0x82, 0x82, 0xfe, 0x82, 0x82, 0x82, 0x82, 0x82, 0xfe, 0x82, 0x82, 0x82, 0x80, 0x00, 
  0x00, 0x80, 0x40, 0x30, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, //开 18

  0x00, 0xf8, 0x01, 0x06, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0xfe, 0x00, 0x00, 
  0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x80, 0x7f, 0x00, 0x00, //门 19

  0x00, 0x00, 0xf0, 0x10, 0x10, 0x10, 0x10, 0xff, 0x10, 0x10, 0x10, 0x10, 0xf0, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x0f, 0x04, 0x04, 0x04, 0x04, 0xff, 0x04, 0x04, 0x04, 0x04, 0x0f, 0x00, 0x00, 0x00, //中 20

  0x00, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //… 21

  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xff, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 
  0x80, 0x80, 0x40, 0x20, 0x10, 0x0c, 0x13, 0x60, 0x03, 0x0c, 0x10, 0x20, 0x40, 0x80, 0x80, 0x00, //太 22

  0x90, 0x88, 0x87, 0xfc, 0x84, 0x84, 0x80, 0x02, 0xf2, 0x12, 0x12, 0x12, 0x12, 0xf2, 0x02, 0x00, 
  0x80, 0x60, 0x18, 0x07, 0x08, 0x30, 0x00, 0x40, 0x45, 0x59, 0x41, 0x41, 0x51, 0x4d, 0x40, 0x00, //短 23

  0x10, 0x10, 0x14, 0xd4, 0x54, 0x54, 0x54, 0xfc, 0x52, 0x52, 0x52, 0xd3, 0x12, 0x10, 0x10, 0x00, 
  0x40, 0x40, 0x50, 0x57, 0x55, 0x55, 0x55, 0x7f, 0x55, 0x55, 0x55, 0x57, 0x50, 0x40, 0x40, 0x00, //重 24

  0x40, 0x40, 0x42, 0xcc, 0x00, 0x90, 0x90, 0x90, 0x90, 0x90, 0xff, 0x10, 0x11, 0x16, 0x10, 0x00, 
  0x00, 0x00, 0x00, 0x3f, 0x10, 0x28, 0x60, 0x3f, 0x10, 0x10, 0x01, 0x0e, 0x30, 0x40, 0xf0, 0x00, //试 25

  0x00, 0x02, 0x02, 0x02, 0x02, 0x82, 0x42, 0xf2, 0x0e, 0x42, 0x82, 0x02, 0x02, 0x02, 0x00, 0x00, 
  0x10, 0x08, 0x04, 0x02, 0x01, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x01, 0x02, 0x0c, 0x00, 0x00, //不 26

  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //一 27

  0x42, 0x62, 0x5a, 0xc6, 0x52, 0x62, 0xc2, 0x20, 0xd8, 0x17, 0x10, 0x10, 0xf0, 0x10, 0x10, 0x00, 
  0x40, 0xc4, 0x44, 0x7f, 0x24, 0x24, 0xa0, 0x40, 0x21, 0x16, 0x08, 0x16, 0x21, 0x40, 0x80, 0x00 //致 28

};

/* 生成实心菱形图标的16*16点阵*/
const uint8_t nonside[32] =
{
  0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 
  0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01, 0x00, 0x00 //◆0,
};

void OLED_WrDat(uint8_t data)
{
  OLED_DC_SET();//数据
  HAL_SPI_Transmit(&hspi2, &data, 1, 1);
}
void OLED_WrCmd(uint8_t cmd)
{
  OLED_DC_CLR();//命令
  HAL_SPI_Transmit(&hspi2, &cmd, 1, 1);
}
void OLED_Start_DMA(uint8_t data[8][128], size_t size)
{
  OLED_DC_SET();//数据
  HAL_SPI_Transmit_DMA(&hspi2, (uint8_t *)data, size);
}
void OLED_Stop_DMA()
{
  HAL_SPI_DMAStop(&hspi2);
}

void OLED_Init(void)
{
  //复位
  OLED_RST_CLR();
  HAL_Delay(50);
  OLED_RST_SET();

  OLED_WrCmd(0xae); //--关闭面板（睡眠模式）
  OLED_WrCmd(0x20); OLED_WrCmd(0x02); //--设置 Page Addressing Mode (0x00/0x01/0x02)
  OLED_WrCmd(0xa1); //--设置左右反转（0xa0左右反置 0xa1正常）
  OLED_WrCmd(0xa6); //--设置正常/反色显示（0xa6正常/0xa7反色）
  OLED_WrCmd(0xa8); OLED_WrCmd(0x3f); //--设置多路复用率(0x0f~0x03f)
  OLED_WrCmd(0xb0); //--设置 Page Addressing Mode 的页开始地址(0xb0~0xb7)
  OLED_WrCmd(0xc8); //--设置上下反转（0xc0上下反置 0xc8正常）
  OLED_WrCmd(0x8d); OLED_WrCmd(0x14);//--设置电荷泵的打开与关闭（0x10关闭 0x14打开）
  // OLED_WrCmd(0x00); //---set low column address
  // OLED_WrCmd(0x10); //---set high column address
  OLED_WrCmd(0x40); //--set start line address  Set Mapping RAM Display Start Line (0x40~0x7F)
  OLED_WrCmd(0x81); OLED_WrCmd(0x01); //--设置对比度（亮度）（0x00~0xFF，RST：0x7F）
  OLED_WrCmd(0xd3); OLED_WrCmd(0x00); //-set display offset	Shift Mapping RAM Counter (0x00~0x3F)
  OLED_WrCmd(0xd5); OLED_WrCmd(0x80); //--set display clock divide ratio/oscillator frequency
  // OLED_WrCmd(0xd9); OLED_WrCmd(0x22); //--set Pre-Charge Period
  // OLED_WrCmd(0xda); OLED_WrCmd(0x12);//--set com pins hardware configuration
  // OLED_WrCmd(0xdb); OLED_WrCmd(0x40); //--set VCOMH Deselect Level
  // OLED_WrCmd(0xa4); //--关闭强制点亮整个面板 (0xa4继续显示/0xa5强制点亮)
  OLED_WrCmd(0xaf); //--打开面板
  OLED_Fill(0x00);  //初始清屏
  OLED_Set_Pos(0, 0);
}

void OLED_UpsideDown(uint8_t upside_down)
{
  if (upside_down)
    OLED_WrCmd(0xc0); //上下反置
  else
    OLED_WrCmd(0xc8); //正常
}

void OLED_AddressMode(uint8_t address_mode)
{
  OLED_WrCmd(0x20);
  if (address_mode == 0)
    OLED_WrCmd(0x00);//Horizontal addressing mode
  else if (address_mode == 1)
    OLED_WrCmd(0x01);//Vertical addressing mode
  else
    OLED_WrCmd(0x02);//Page addressing mode
}

/*设置起始地址
 *Y轴是按8格递进的，y轴0~63，只能按8格的倍数显示，
 *因为列行式只能按8个字节进行
 */
void OLED_Set_Pos(uint8_t x, uint8_t y)
{
  OLED_WrCmd(0xb0 + (y >> 3));
  OLED_WrCmd(((x & 0xf0) >> 4) | 0x10);
  OLED_WrCmd((x & 0x0f) | 0x00);
}
void OLED_Fill(uint8_t data)
{
  uint8_t y, x;

  for (y = 0; y < 8; y++)
  {
    OLED_WrCmd(0xb0 + y);
    OLED_WrCmd(0x01);
    OLED_WrCmd(0x10);
    for (x = 0; x < 128; x++)
      OLED_WrDat(data);
  }
}
void OLED_CLS(void)
{
  OLED_Fill(0x00);
}
//==============================================================
//函数名：OLED_P6x8Str(uint8_t x,uint8_t y,uint8_t *p)
//功能描述：写入一组标准ASCII字符串
//参数：显示的位置（x,y），y为页范围0～7，要显示的字符串
//返回：无
//==============================================================
void OLED_P6x8Str(uint8_t x, uint8_t y, const char *ch)
{
  uint8_t c = 0, i = 0, j = 0;
  y *= 8;

  while (*(ch + j) != '\0')
  {
    c = *(ch + j) - 32;
    if (x > 121)
    {
      x = 0;
      y += 8;
    }
    OLED_Set_Pos(x, y);
    for (i = 0; i < 6; i++)
    {
      OLED_WrDat(*(F6x8 + c * 6 + i));
    }
    x += 6;
    j++;
  }
}
//==============================================================
//函数名：OLED_P8x16Str(uint8_t x,uint8_t y,uint8_t *p)
//功能描述：写入一组标准ASCII字符串
//参数：显示的位置（x,y），y为页范围0～7，要显示的字符串
//返回：无
//==============================================================
void OLED_P8x16Str(uint8_t x, uint8_t y, const char *ch)
{
  uint8_t c = 0, i = 0, j = 0;
  y *= 8;

  while (*(ch + j) != '\0')
  {
    c = *(ch + j) - 32;
    if (x > 120)
    {
      x = 0;
      y++;
    }
    OLED_Set_Pos(x, y);
    for (i = 0; i < 8; i++)
    {
      OLED_WrDat(*(F8X16 + c * 16 + i));
    }
    OLED_Set_Pos(x, y + 8);
    for (i = 0; i < 8; i++)
    {
      OLED_WrDat(*(F8X16 + c * 16 + i + 8));
    }
    x += 8;
    j++;
  }
}
/**
 * @brief 输出汉字字符串
 *
 * @param x 起始横坐标（0~112）
 * @param y 起始纵坐标（0~6）
 * @param ch 汉字字符串
 */
void OLED_P16x16Str(uint8_t x, uint8_t y, const char *ch)
{
  uint8_t i = 0, j, k;
  uint16_t addr;
  size_t size = strlen(ch) / 3;//UTF-8汉字占3个字节
  y *= 8;

  while (i < size)
  {
    j = k = 0;
    addr = 1;//非法字模下标表示不存在的字符
    while (F16x16_Idx[k] != '\0')
    {
      if (strncmp(F16x16_Idx + k * 3, ch + i * 3, 3) == 0)//在索引中寻找字符
      {
        addr = k * 32; //定位字模起始下标
        break;
      }
      k++;
    }
    //换行
    if (x > 112)
    {
      x = 0;
      y += 16;
    }
    if (addr != 1) // 显示汉字
    {
      OLED_Set_Pos(x, y);
      for (j = 0; j < 16; j++)
      {
        OLED_WrDat(*(F16x16 + addr));
        addr += 1;
      }
      OLED_Set_Pos(x, y + 8);
      for (j = 0; j < 16; j++)
      {
        OLED_WrDat(*(F16x16 + addr));
        addr += 1;
      }
    }
    else //不存在的字符，显示菱形
    {
      addr = 0;
      OLED_Set_Pos(x, y);
      for (j = 0; j < 16; j++)
      {
        OLED_WrDat(*(nonside + addr));
        addr += 1;
      }
      OLED_Set_Pos(x, y + 8);
      for (j = 0; j < 16; j++)
      {
        OLED_WrDat(*(nonside + addr));
        addr += 1;
      }
    }
    x += 16;
    i += 1;
  }
}
//==============================================================
//函数名： void Draw_BMP(uint8_t x,uint8_t y)
//功能描述：显示BMP图片128×64
//参数：起始点坐标(x,y),x的范围0～127，y为页的范围0～63
//返回：无
//==============================================================
void OLED_BMP(uint8_t x0, uint8_t y0, const uint8_t *bmp)
{
  uint16_t ii = 0;
  uint8_t x, y;

  OLED_Set_Pos(0, 0);
  OLED_AddressMode(0);
  for (y = y0; y < 64; y += 8)
  {
    for (x = x0; x < 128; x++)
    {
      OLED_WrDat(bmp[ii++]);
    }
  }
  OLED_AddressMode(2);
}
